PangoFontDescription *font;
StThemeNode *root_node;
StTheme *theme;
+
+ /* set of StThemeNode */
+ GHashTable *nodes;
};
struct _StThemeContextClass {
(gpointer) st_theme_context_changed,
context);
+ if (context->nodes)
+ g_hash_table_unref (context->nodes);
if (context->root_node)
g_object_unref (context->root_node);
if (context->theme)
"resolution-changed",
G_CALLBACK (st_theme_context_changed),
context);
+
+ context->nodes = g_hash_table_new_full ((GHashFunc) st_theme_node_hash,
+ (GEqualFunc) st_theme_node_equal,
+ g_object_unref, NULL);
}
/**
{
StThemeNode *old_root = context->root_node;
context->root_node = NULL;
+ g_hash_table_remove_all (context->nodes);
emit_changed (context);
return context->root_node;
}
+
+/**
+ * st_theme_context_intern_node:
+ * @context: a #StThemeContext
+ * @node: a #StThemeNode
+ *
+ * Return an existing node matching @node, or if that isn't possible,
+ * @node itself.
+ *
+ * Return value: (transfer none): a node with the same properties as @node
+ */
+StThemeNode *
+st_theme_context_intern_node (StThemeContext *context,
+ StThemeNode *node)
+{
+ StThemeNode *mine = g_hash_table_lookup (context->nodes, node);
+
+ /* this might be node or not - it doesn't actually matter */
+ if (mine != NULL)
+ return mine;
+
+ g_hash_table_add (context->nodes, g_object_ref (node));
+ return node;
+}
StThemeNode * st_theme_context_get_root_node (StThemeContext *context);
+StThemeNode * st_theme_context_intern_node (StThemeContext *context,
+ StThemeNode *node);
+
G_END_DECLS
#endif /* __ST_THEME_CONTEXT_H__ */
return TRUE;
}
+guint
+st_theme_node_hash (StThemeNode *node)
+{
+ guint hash = GPOINTER_TO_UINT (node->parent_node);
+
+ hash = hash * 33 + GPOINTER_TO_UINT (node->context);
+ hash = hash * 33 + GPOINTER_TO_UINT (node->theme);
+ hash = hash * 33 + ((guint) node->element_type);
+
+ if (node->element_id != NULL)
+ hash = hash * 33 + g_str_hash (node->element_id);
+
+ if (node->inline_style != NULL)
+ hash = hash * 33 + g_str_hash (node->inline_style);
+
+ if (node->element_classes != NULL)
+ {
+ gchar **it;
+
+ for (it = node->element_classes; *it != NULL; it++)
+ hash = hash * 33 + g_str_hash (*it) + 1;
+ }
+
+ if (node->pseudo_classes != NULL)
+ {
+ gchar **it;
+
+ for (it = node->pseudo_classes; *it != NULL; it++)
+ hash = hash * 33 + g_str_hash (*it) + 1;
+ }
+
+ return hash;
+}
+
static void
ensure_properties (StThemeNode *node)
{
StTheme *st_theme_node_get_theme (StThemeNode *node);
gboolean st_theme_node_equal (StThemeNode *node_a, StThemeNode *node_b);
+guint st_theme_node_hash (StThemeNode *node);
GType st_theme_node_get_element_type (StThemeNode *node);
const char *st_theme_node_get_element_id (StThemeNode *node);
if (priv->theme_node == NULL)
{
+ StThemeContext *context;
+ StThemeNode *tmp_node;
StThemeNode *parent_node = NULL;
ClutterStage *stage = NULL;
ClutterActor *parent;
else
pseudo_class = direction_pseudo_class;
- priv->theme_node = st_theme_node_new (st_theme_context_get_for_stage (stage),
- parent_node, priv->theme,
- G_OBJECT_TYPE (widget),
- clutter_actor_get_name (CLUTTER_ACTOR (widget)),
- priv->style_class,
- pseudo_class,
- priv->inline_style);
+ context = st_theme_context_get_for_stage (stage);
+ tmp_node = st_theme_node_new (context, parent_node, priv->theme,
+ G_OBJECT_TYPE (widget),
+ clutter_actor_get_name (CLUTTER_ACTOR (widget)),
+ priv->style_class,
+ pseudo_class,
+ priv->inline_style);
if (pseudo_class != direction_pseudo_class)
g_free (pseudo_class);
+
+ priv->theme_node = g_object_ref (st_theme_context_intern_node (context,
+ tmp_node));
+ g_object_unref (tmp_node);
}
return priv->theme_node;